package com.sparrow.common.mergeupdate.impl;

import com.sparrow.common.mergeupdate.MergeUpdateBox;
import com.sparrow.common.thread.IdExecutorGroup;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 合并更新之 - 抖动合并（防抖）
 * 每次调用 tryMergeSchedule 都会重新调度一次，直到一段时间没有新的调用才会触发任务
 */
public class DebounceMergeBox implements MergeUpdateBox {

    private final Map<Object, DebounceMergeScheduler> dataMap = new ConcurrentHashMap<>();

    public MergeUpdateBox.MergeUpdateScheduler getMergeUpdateScheduler(Object key) {
        return dataMap.computeIfAbsent(key, k -> new DebounceMergeScheduler());
    }

    public static class DebounceMergeScheduler implements MergeUpdateBox.MergeUpdateScheduler {
        private volatile ScheduledFuture<?> future;

        public synchronized void tryMergeSchedule(IdExecutorGroup executorGroup, long id, String taskName, Runnable task, long delay, TimeUnit unit) {
            // 取消之前的任务
            if (future != null && !future.isDone()) {
                future.cancel(false);
            }
            // 重新调度
            future = executorGroup.schedule(id, taskName, () -> {
                task.run();
            }, delay, unit);
        }
    }
}

